package com.tanhua.manage.service;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.manage.mapper.LoginUserMapper;
import com.tanhua.manage.pojo.Admin;
import com.tanhua.manage.vo.LoginUserVo;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class LoginService {

    @Autowired
    private LoginUserMapper loginUserMapper;

    @Value("${jwt.secret}")
    private String secret;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;


    /**
     *验证账号和密码，生成token返回
     * @param username
     * @param password
     * @return
     */
    public String checkUser(String username, String password) {

        QueryWrapper warpper = new QueryWrapper();
        warpper.eq("username",username);
        Admin admin = loginUserMapper.selectOne(warpper);
        //用户账号不存在
        if (admin == null){
            log.info("用户账号不存在");
            return null;
        }

        //验证密码和账号是否匹配
        if (!StrUtil.equals(password,admin.getPassword())){
            log.info("账号或密码错误");
            return null;
        }

        //生成token
        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put("id", admin.getId());

        // 生成token
        String token = Jwts.builder()
                .setClaims(claims) //payload，存放数据的位置，不能放置敏感数据，如：密码等
                .signWith(SignatureAlgorithm.HS256, secret) //设置加密方法和加密盐
                .setExpiration(new DateTime().plusHours(1).toDate()) //设置过期时间，1小时后过期
                .compact();

        return token;
    }


    /**
     * 解析token
     * @param token
     * @return
     */
    public Admin queryUserByToken(String token) {
        try {
            // 通过token解析数据
            Map<String, Object> body = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();

            Admin admin = new Admin();
            admin.setId(Long.valueOf(body.get("id").toString()));

            //数据缓存时，需要设置过期时间，过期时间要与token的时间一致

            String redisKey = "TANHUA_USER_USERNAME_" + admin.getId();
            if (this.redisTemplate.hasKey(redisKey)) {
                String username = this.redisTemplate.opsForValue().get(redisKey);
                admin.setUsername(username);
            } else {
                //查询数据库
                Admin a = this.loginUserMapper.selectById(admin.getId());

                //在jwt中的过期时间的单位为：秒
                long timeout = Long.valueOf(body.get("exp").toString()) * 1000 - System.currentTimeMillis();
                this.redisTemplate.opsForValue().set(redisKey, a.getUsername(), timeout, TimeUnit.MILLISECONDS);
            }

            return admin;
        } catch (ExpiredJwtException e) {
            log.info("token已经过期！ token = " + token);
        } catch (Exception e) {
            log.error("token不合法！ token = " + token, e);
        }
        return null;
    }


    /**
     * 返回响应的vo
     * @param id
     * @return
     */
    public LoginUserVo getLoginUser(Long id) {

        LoginUserVo loginUserVo = new LoginUserVo();
        Admin admin = loginUserMapper.selectById(id);

        loginUserVo.setUid(String.valueOf(admin.getId()));
        loginUserVo.setUsername(admin.getUsername());
        loginUserVo.setAvatar(admin.getAvatar());

        return loginUserVo;
    }
}
